const supportsNativeTextEncoder = typeof TextEncoder !== "undefined";
const supportsNativeTextDecoder = typeof TextDecoder !== "undefined";

export function encodeBase64(str: string) {
  if (supportsNativeTextEncoder) {
    let bytes = new TextEncoder().encode(str);
    const binString = Array.from(bytes, (byte) => String.fromCodePoint(byte)).join("");
    return btoa(binString);
  } else
    return btoa(
      encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, (_match, p1) =>
        String.fromCharCode(Number("0x" + p1))
      )
    );
}
export function decodeBase64(base64: string) {
  if (supportsNativeTextDecoder) {
    const binString = atob(base64);
    const bytes = Uint8Array.from(binString, (c) => c.charCodeAt(0));
    return new TextDecoder().decode(bytes);
  } else
    decodeURIComponent(
      atob(base64)
        .split("")
        .map((c) => "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2))
        .join("")
    );
}
